import { TComponent } from '@material/typeing';
import Overlay, { OverlayProps } from '../overlay';
import { FC, useEffect, useRef } from 'react';
import KTransition, { CssType } from '../transtion';
import KRootPortal, { RootPortalRef } from '../root-portal';
import $style from './index.scss';
import { ClassValue } from 'react-runtime-clsx';

export type PlacementType = 'left' | 'bottom' | 'top' | 'right' | 'center';
export interface PopupProps extends TComponent {
    placement?: 'left' | 'top' | 'center' | 'bottom';
    visible?: boolean;
    defaultClass?: ClassValue;
    hasOverlayTransition?: boolean;
    hasPopupTransition?: boolean;
    isOverlayClose?: boolean;
    overlayProps?: OverlayProps;
    autoDestroy?: boolean;
    entering?: CssType;
    exiting?: CssType;
    hasOverlay?: boolean;
    appear?: boolean; // 第一次挂载时执执行输入转换
    unmountOnExit?: boolean; // 完成退出后卸载组件
    mountOnEnter?: boolean; // 开始时才安装组件
}

export const Popup: FC<PopupProps> = function (props) {
    const {
        overlayProps,
        children,
        hasOverlayTransition = true,
        entering,
        defaultClass,
        exiting,
        visible,
        hasPopupTransition = true,
        hasOverlay = true,
        placement = 'bottom',
        appear = true,
        unmountOnExit = true,
        mountOnEnter = true
    } = props;
    const enteringStyle = entering ? entering : $style[`entering-${placement}`];
    const exitingStyle = exiting ? exiting : $style[`exiting-${placement}`];
    const defaultStyle = defaultClass ? defaultClass : $style[`default-${placement}`];
    const overlayDefaultProps = { appear, unmountOnExit, mountOnEnter, ...overlayProps };
    const portalRef = useRef<RootPortalRef>(null);
    const cacheOverRef = useRef<HTMLElement[]>([]);
    useEffect(() => {
        if (!hasOverlayTransition && !hasPopupTransition && !visible && portalRef.current) {
            portalRef.current.destory();
        }
    }, [hasOverlayTransition, hasPopupTransition, visible]);
    const destory = () => {
        if (!portalRef.current) {
            return;
        }
        unmountOnExit && portalRef.current.destory();
        cacheOverRef.current.forEach((el) => {
            el.setAttribute('style', 'display: none;');
        });
        cacheOverRef.current = [];
    };

    const overTransition = (node: HTMLElement) => {
        const isDestory = !visible && portalRef.current;
        if (!isDestory) {
            return;
        }
        cacheOverRef.current.push(node);
        if (hasPopupTransition && cacheOverRef.current.length === 2) {
            destory();
            return;
        }
    };
    return (
        <KRootPortal
            visible={visible}
            ref={portalRef}
        >
            <Overlay
                hasTransition={hasOverlayTransition}
                hasOverlay={hasOverlay}
                visible={visible}
                exited={(node) => overTransition(node)}
                {...overlayDefaultProps}
            ></Overlay>
            <KTransition
                hasTransition={hasPopupTransition}
                visible={visible}
                appear={appear}
                mountOnEnter={mountOnEnter}
                unmountOnExit={unmountOnExit}
                enter={(node) => {
                    if (!node) {
                        return;
                    }
                    node.setAttribute('style', 'display: flex;');
                }}
                entering={enteringStyle}
                exiting={exitingStyle}
                exited={(node) => overTransition(node)}
            >
                <div
                    className={[
                        $style.popup,
                        hasPopupTransition ? defaultStyle : '',
                        $style[placement]
                    ]}
                >
                    {children}
                </div>
            </KTransition>
        </KRootPortal>
    );
};

export default Popup;
